/**
* @Name: websocket.js
* @Author: liuwei
* @Description: websocket封装
* @MainFunction: websocket 需要时按需引入即可(根据项目具体配置)
* */
const productConfig = window.productConfig
const baseURL = productConfig.wsUrl
const wsPath = productConfig.wsPath

class CreateWebSocket {
  /*
        1.接受参数形式
        param = {
            url: 'wss://xxxxx', //传入的url(可选)
            callback: vm.getSocketMsg, //接受数据的回调函数
            msg: { actionSignal: 'enterSystemMonitor', token: sessionStorage.token } //传入的send值
        }
        2.使用方式
        vm.socket = new CreateWebSocket(param);
        vm.socket.initWebSocket();
        3.需要频繁使用，适当调整将CreateWebSocket实例对象直接挂载到Vue原型上即可
    */
  constructor(param) {
    // websocket的实例对象
    this.websocket = null;
    // 连接状态
    this.isConnect = false;
    // 重连定时器
    this.timeoutNum = null;
    // 传递的参数
    this.param = param;
    // 存储的回调函数
    this.callback = param.callback;
    // 发送的参数
    this.msg = param.msg || '';
    // 连接的参数地址
    this.paramUrl = param.url ? param.url : wsPath;
    // 最终的url
    this.url = `${baseURL}${this.paramUrl}`;
    // 消息队列
    this.messageQueue = [];
  }

  // 连接websocket的地址
  initWebSocket() {
    if (this.websocket) {
      this.websocket.close();
    }
    this.url = `${baseURL}${this.paramUrl}`;
    this.websocket = new WebSocket(this.url);
    this.connect();
  }

  // 初始化连接状态
  connect() {
    this.websocket.onclose = (e) => {
      this.isConnect = false;
    };
    // 错误的回调
    this.websocket.onerror = (e) => {
      this.reconnectSocket();
    };
    // 成功的连接
    this.websocket.onopen = () => {
      this.isConnect = true;
      // 发送队列中的消息
      while(this.messageQueue.length > 0) {
        const queuedMsg = this.messageQueue.shift();
        this.send(queuedMsg);
      }
    };

    // 接受传递的回调函数，并接受返回的数据
    this.websocket.onmessage = (e) => {
      try {
        this.callback.call(this, JSON.parse(e.data), e);
      } catch (error) {
        console.log(e.data);
      }
    };
  }

  // 重连websocket
  reconnectSocket() {
    if (this.isConnect) return;
    this.isConnect = true; // 防止重复重连
    this.timeoutNum && clearTimeout(this.timeoutNum);
    this.timeoutNum = setTimeout(() => {
      this.initWebSocket();
      this.isConnect = false;
    }, 10000);
  }

  // websocket发送信号
  send(msg) {
    if (msg.url && msg.url !== this.paramUrl) {
      this.paramUrl = msg.url;
      this.messageQueue.push(msg);
      this.initWebSocket();
      return;
    }

    if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {
      this.messageQueue.push(msg);
      if (!this.websocket || this.websocket.readyState === WebSocket.CLOSED) {
        this.initWebSocket();
      }
      return;
    }
    
    const messageToSend = typeof msg === 'object' ? JSON.stringify(msg) : msg;
    this.websocket.send(messageToSend);
  }

  // 关闭websocket连接
  close() {
    this.messageQueue = []; // 清空消息队列
    if (this.websocket) {
        this.websocket.close();
        this.websocket = null;
    }
    this.isConnect = false;
    this.timeoutNum && clearTimeout(this.timeoutNum);
  }

  // 设置更新回调
  setUpdateCallback(callback) {
    this.onUpdate = callback;
  }
}

export default CreateWebSocket;
